// -*- c-basic-offset: 2 default-tab-width: 2 indent-tabs-mode: t -*-
// vim: autoindent tabstop=2 noexpandtab shiftwidth=2 softtabstop=2
/*
 * Any.cpp
 *
 *  Created on: Dec 6, 2011
 *      Author: bakiras
 */

#include "Any.h"
#include "Array.h"
#include "Symbol.h"

using namespace R;

// Constructor with type as parameter.
RVirtualTable::RVirtualTable(word_t ID, RVirtualTable *vt, bool hasDestructor){
	memcpy(this, vt, getBaseSize()*sizeof(word_t));
	type = ID;

	if(!hasDestructor)
		destructor = 0;
}

void Any::markAndTrace(void* source, void* ptr, word_t closure) {
	vmkit::Collector::markAndTrace(source, ptr, closure);
}

void Any::markAndTraceRoot(void* ptr, word_t closure) {
	vmkit::Collector::markAndTraceRoot(ptr, closure);
}

// returns object's type (type id)
word_t Any::getType(Any* self) {
	R_PARAM(self);
#ifdef R_64
	return ((OBJHeader)(self->header)).headerFields.objID;
#else
	return self->getRVirtualTable()->type;
#endif
}

RVirtualTable* Any::getRVirtualTable() {
	asSelf(Any);
  return static_cast<RVirtualTable*>(self->gc::getVirtualTable());
}

word_t Any::TType(word_t type1, word_t type2) {
  return (type1 > type2) ? (type1) : (type2);
}

void* Any::operator new(size_t sz, VirtualTable *VT) {
	void* res;
	res = gc::operator new(sz, VT);
// Only 8 bits seems used in the header.
// Maybe the next 8 for hash but I'm not sure
// Let's use the 8 next for the type iff we are in 64b
// the 32 following will be used for tags.
// TODO maybe do this even in 32 bits because we don't have so many tags :p
#ifdef R_64
	((OBJHeader*)(&static_cast<Any*>(res)->header))->headerFields.objID = static_cast<RVirtualTable*>(VT)->type;
#endif
	return res;
}
